﻿namespace A1;

class Program
{
    static readonly OrderService OrderService = new ();

    static void Main(string[] args)
    {
        bool running = true;
        Console.WriteLine("Welcome to the Order Management System!");

        while (running)
        {
            Console.WriteLine("\nPlease choose an option:");
            Console.WriteLine("1. Add a new order");
            Console.WriteLine("2. Remove an existing order");
            Console.WriteLine("3. Modify an existing order");
            Console.WriteLine("4. Query orders");
            Console.WriteLine("5. Display all orders");
            Console.WriteLine("6. Export orders to XML");
            Console.WriteLine("7. Import orders from XML");
            Console.WriteLine("8. Exit");
            Console.Write("> ");

            var input = Console.ReadLine();
            Console.WriteLine();
            switch (input)
            {
                case "1":
                    AddOrder();
                    break;
                case "2":
                    RemoveOrder();
                    break;
                case "3":
                    ModifyOrder();
                    break;
                case "4":
                    QueryOrders();
                    break;
                case "5":
                    DisplayAllOrders();
                    break;
                case "6":
                    ExportOrders();
                    break;
                case "7":
                    ImportOrders();
                    break;
                case "8":
                    running = false;
                    Console.WriteLine("Exiting Order Management System. Goodbye!");
                    break;
                default:
                    Console.WriteLine("Invalid option, please try again.");
                    break;
            }
        }
    }

    static void AddOrder()
    {
        Console.WriteLine("Adding a new order...");
        Console.Write("Enter Order ID: ");
        int orderId;
        while (!int.TryParse(Console.ReadLine(), out orderId))
        {
            Console.Write("Please enter the Order ID Again for a number:");
        }
        
        Console.Write("Enter Customer Name: ");
        string? customerName = Console.ReadLine();
        while (string.IsNullOrWhiteSpace(customerName))
        {
            Console.Write("Please enter a non empty word: ");
            customerName = Console.ReadLine();
        }
        
        var orderDetails = new List<OrderDetails>();
        while (true)
        {
            Console.Write("Enter Product Name (or 'done' to finish): ");
            string? productName = Console.ReadLine();
            while (string.IsNullOrWhiteSpace(productName))
            {
                Console.Write("Please enter a non empty word: ");
                productName = Console.ReadLine();
            }
            if (productName.ToLower() == "done") break;
            
            decimal productPrice;
            Console.Write("Enter Product Price: ");
            while (!decimal.TryParse(Console.ReadLine(), out productPrice))
            {
                Console.Write("Please enter the Product Price Again for a number:");
            }

            int quantity;
            Console.Write("Enter Quantity: ");
            while (!int.TryParse(Console.ReadLine(), out quantity))
            {
                Console.Write("Please enter the Quantity Again for a number:");
            }

            orderDetails.Add(new OrderDetails(new Product(productName, productPrice), quantity));
        }

        var order = new Order(orderId, new Customer(customerName), orderDetails);
        OrderService.AddOrder(order);
        Console.WriteLine("Order added successfully.");
    }

    static void RemoveOrder()
    {
        
        int orderId;
        Console.Write("Enter Order ID to remove: ");
        while (int.TryParse(Console.ReadLine(), out orderId))
        {
            Console.Write("Please enter the Order ID Again for a number:");
        }

        OrderService.RemoveOrder(orderId);
        Console.WriteLine("Order removed successfully.");
    }

    static void ModifyOrder()
    {
        try
        {
            int orderId;
            Console.Write("Enter Order ID to remove: ");
            while (!int.TryParse(Console.ReadLine(), out orderId))
            {
                Console.Write("Please enter the Order ID Again for a number:");
            }
            
            var existingOrder = OrderService.QueryOrders(sp => sp.OrderId == orderId).FirstOrDefault();
            
            if (existingOrder is null)
            {
                Console.WriteLine("Order not found.");
                return;
            }

            // 克隆 order 以便于进行修改
            var newOrderDetails = new List<OrderDetails>(existingOrder.OrderDetails);

            Console.Write("Enter new Customer Name (leave blank to keep current): ");
            string customerName = Console.ReadLine()!;
            Customer newCustomer = !string.IsNullOrWhiteSpace(customerName) ? new Customer(customerName) : existingOrder.Customer;
            
            newOrderDetails.Clear();

            while (true)
            {
                Console.Write("Enter Product Name (or 'done' to finish): ");
                string? productName = Console.ReadLine();
                while (string.IsNullOrWhiteSpace(productName))
                {
                    Console.Write("Please enter a non empty word: ");
                    productName = Console.ReadLine();
                }
                if (productName.ToLower() == "done") break;

            
                decimal productPrice;
                Console.Write("Enter Product Price: ");
                while (!decimal.TryParse(Console.ReadLine(), out productPrice))
                {
                    Console.Write("Please enter the Product Price Again for a number:");
                }

                int quantity;
                Console.Write("Enter Quantity: ");
                while (!int.TryParse(Console.ReadLine(), out quantity))
                {
                    Console.Write("Please enter the Quantity Again for a number:");
                }

                newOrderDetails.Add(new OrderDetails(new Product(productName, productPrice), quantity));
            }

            var modifiedOrder = existingOrder with { Customer = newCustomer, OrderDetails = newOrderDetails };
            OrderService.ReplaceOrder(orderId, modifiedOrder);
            Console.WriteLine("Order modified successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }


    static void QueryOrders()
    {
        Console.WriteLine("==========[QUERY]==========");
        Console.Write("Enter Customer Name to query: ");
        string customerName = Console.ReadLine()!;
        var queriedOrders = OrderService.QueryOrders(sp => sp.Customer.Name.Contains(customerName, StringComparison.OrdinalIgnoreCase));
        if (!queriedOrders.Any())
        {
            Console.WriteLine("Not found any orders.");
            return;
        }
        
        foreach (var order in queriedOrders)
        {
            Console.WriteLine(order);
        }
    }

    static void DisplayAllOrders()
    {
        Console.WriteLine("==========[QUERY]==========");
        Console.WriteLine("All orders:");
        foreach (var order in OrderService.GetAllOrders())
        {
            Console.WriteLine(order);
        }
    }
    
    static void ExportOrders()
    {
        Console.Write("Enter the file path to export the orders to XML: ");
        string filePath = Console.ReadLine() ?? string.Empty;
        try
        {
            OrderService.Export(filePath);
            Console.WriteLine($"Orders successfully exported to {filePath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred while exporting orders: {ex.Message}");
        }
    }

    static void ImportOrders()
    {
        Console.Write("Enter the file path to import the orders from XML: ");
        string filePath = Console.ReadLine() ?? string.Empty;
        try
        {
            OrderService.Import(filePath);
            Console.WriteLine($"Orders successfully imported from {filePath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred while importing orders: {ex.Message}");
        }
    }
}
